import xlrd2
from common.settings import logger
from typing import List, Dict, Union
from utils.readFileUtils.yaml_control import YamlHandler
from utils.otherUtils.file_control import check_file_path
from common.constant import ExcelHead, ApiInfo


class ExcelHandler:

    def __init__(self, api_info: Dict):
        self.api_info = api_info

    @property
    def test_data_file_path(self) -> Union[str, None]:
        return self.api_info.get(ApiInfo.TEST_DATA_FILE_PATH.value)

    @staticmethod
    def is_empty_row(sheet, row_num) -> bool:
        for col in range(sheet.ncols):
            cell_value = sheet.cell_value(row_num, col)
            if cell_value:
                return False
        return True

    def get_excel_data(self) -> List[Dict]:

        test_data_file_path = check_file_path(self.test_data_file_path)

        # 读取excel文件
        excel_data = xlrd2.open_workbook(test_data_file_path)
        sheet = excel_data.sheet_by_name('测试数据')
        rows = sheet.nrows
        if rows <= 1:
            raise ValueError('该execl文件只有表头，无测试数据')

        # 从表头获取需要的字段，并记录其索引
        head_lst = sheet.row_values(0)
        logger.info(f'表头：{head_lst}')
        head_index_mapping = {}
        for i in range(len(head_lst)):
            head = head_lst[i]
            if head == ExcelHead.ID.value:
                head_index_mapping[head] = i
            elif head == ExcelHead.SKIP.value:
                head_index_mapping[head] = i
            elif ExcelHead.REQUEST_PARAMS.value in head:
                head_index_mapping[head] = i
            elif ExcelHead.CHECK_POINT.value in head:
                head_index_mapping[head] = i
            elif ExcelHead.UPLOAD_FILE.value in head:
                head_index_mapping[head] = i
        if not head_index_mapping:
            raise ValueError('无测试数据，请检查excel文件')
        logger.info(f'需要的表头和对应的索引:{head_index_mapping}')

        # 封装数据：sheet中的每一行为一个字典，一个sheet为一个列表
        result = []
        for i in range(1, rows):
            row_data = {}
            if self.is_empty_row(sheet, i):
                continue
            row_value_lst = sheet.row_values(i)
            if row_value_lst[head_index_mapping[ExcelHead.SKIP.value]]:
                continue
            request_params = {}
            check_point = {}
            upload_file = {}
            for item in head_index_mapping.items():
                if ExcelHead.REQUEST_PARAMS.value in item[0]:
                    params = item[0].split('-')[1]
                    request_params[params] = row_value_lst[item[1]]
                elif ExcelHead.CHECK_POINT.value in item[0]:
                    if row_value_lst[item[1]]:
                        check_point[item[0]] = row_value_lst[item[1]]
                elif ExcelHead.UPLOAD_FILE.value in item[0]:
                    upload_file[item[0]] = row_value_lst[item[1]]
                else:
                    row_data[item[0]] = row_value_lst[item[1]]
            row_data[ExcelHead.REQUEST_PARAMS.value] = request_params
            row_data[ExcelHead.CHECK_POINT.value] = check_point
            row_data[ExcelHead.UPLOAD_FILE.value] = upload_file
            # logger.info(json.dumps(row_data, ensure_ascii=False))
            logger.info(row_data)
            # 变成生成器
            # yield row_data
            result.append(row_data)
        logger.info(f'共{len(result)}条用例')
        return result


if __name__ == '__main__':
    myCollection_api_info = YamlHandler('common/api_common_info.yaml', 'api_detail/bilibili/search.yaml', 'bilibili',
                                        'search_all_v2').run()
    res = ExcelHandler(myCollection_api_info).get_excel_data()
